package com.shuma.permissionservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shuma.common.event.OperationLogEvent;
import com.shuma.common.utils.IpUtils;
import com.shuma.common.utils.UserContext;
import com.shuma.permissionservice.domain.pojo.Roles;
import com.shuma.permissionservice.domain.pojo.UserRoles;
import com.shuma.permissionservice.mapper.RolesMapper;
import com.shuma.permissionservice.mapper.UserRolesMapper;
import com.shuma.permissionservice.mq.LogMessageSender;
import com.shuma.permissionservice.service.PermissionService;

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class PermissionServiceImpl implements PermissionService {

    private final RolesMapper rolesMapper;
    private final UserRolesMapper userRolesMapper;
    private final LogMessageSender logMessageSender;

    @Override
    public void bindDefaultRole(Long userId) {
        // 1. 查询默认角色（role_code = 'user'）在 roles 表中的记录
        Roles defaultRole = rolesMapper.selectOne(
                new QueryWrapper<Roles>().eq("role_code", "user")
        );
        if (defaultRole == null) {
            // 2. 若数据库里没配置这个角色，说明系统有误，抛异常提示
            throw new RuntimeException("默认角色 user 不存在");
        }
        // 3. 查询该用户是否已存在角色绑定记录
        UserRoles existing = userRolesMapper.selectOne(
                new QueryWrapper<UserRoles>().eq("user_id", userId)
        );
        if (existing == null) {
            // 4. 若不存在绑定，插入 user_roles 表，给用户绑定“user”角色
            UserRoles userRole = new UserRoles();
            userRole.setUserId(userId);
            userRole.setRoleId(defaultRole.getRoleId());
            userRolesMapper.insert(userRole);
        }
        // 如果已存在，不操作（防止重复绑定）

        // 发送日志消息
        String ip = "unknown";
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            ip = IpUtils.getClientIp(request);
        } catch (Exception e) {
            // 这里捕获异常，防止非web线程或Request为空导致报错
        }
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(userId);
        event.setAction("bind_default_role");
        event.setIp(ip);
        event.setDetail("绑定默认角色 user，roleId=" + defaultRole.getRoleId());

        logMessageSender.send(event);
    }

    @Override
    public String getUserRoleCode(Long userId) {
        UserRoles userRole = userRolesMapper.selectOne(
                new QueryWrapper<UserRoles>().eq("user_id", userId)
        );
        if (userRole == null) {
            return null;
        }
        Roles role = rolesMapper.selectOne(new QueryWrapper<Roles>().eq("role_id", userRole.getRoleId()));
        String roleCode =role != null ? role.getRoleCode() : null;
        //MQ
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(userId);
        event.setAction("get_user_role_code");
        event.setIp(ip);
        event.setDetail("查询到角色 roleId=" + userRole.getRoleId() + ", roleCode=" + roleCode);
        logMessageSender.send(event);

        return roleCode;
    }

    @Override
    public void upgradeToAdmin(Long userId) {
        Roles adminRole = rolesMapper.selectOne(
                new QueryWrapper<Roles>().eq("role_code", "admin")
        );
        if (adminRole == null) {
            throw new RuntimeException("admin 角色不存在");
        }

        UserRoles userRole = userRolesMapper.selectOne(
                new QueryWrapper<UserRoles>().eq("user_id", userId)
        );
        if (userRole == null) {
            userRole = new UserRoles();
            userRole.setUserId(userId);
            userRole.setRoleId(adminRole.getRoleId());
            userRolesMapper.insert(userRole);
        } else {
            userRole.setRoleId(adminRole.getRoleId());
            userRolesMapper.update(userRole, new QueryWrapper<UserRoles>().eq("user_id", userId));
        }
        // MQ 日志
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(UserContext.getUserId());
        event.setAction("upgrade_to_admin");
        event.setIp(ip);
        event.setDetail(UserContext.getUserId()+"将用户升级为 admin，目标用户ID=" + userId + "，roleId=" + adminRole.getRoleId());
        logMessageSender.send(event);
    }

    @Override
    public void downgradeToUser(Long userId) {
        // 1. 获取 "user" 对应的 role_id
        Roles userRole = rolesMapper.selectOne(
                new QueryWrapper<Roles>().eq("role_code", "user")
        );
        if (userRole == null) {
            // 如果 "user" 角色不存在，说明数据库初始化有问题
            throw new RuntimeException("普通用户角色 user 不存在");
        }
        // 2. 查询当前用户是否已经有角色绑定
        UserRoles user = userRolesMapper.selectOne(
                new QueryWrapper<UserRoles>().eq("user_id", userId)
        );
        if (user == null) {
            throw new RuntimeException("该用户尚未绑定任何角色，无法降级");
        }
        // 3. 更新用户角色为 "user"
        user.setRoleId(userRole.getRoleId());
        userRolesMapper.update(user, new QueryWrapper<UserRoles>().eq("user_id", userId));

        // MQ 日志
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(UserContext.getUserId());
        event.setAction("downgrade_to_user");
        event.setIp(ip);
        event.setDetail(UserContext.getUserId()+"将用户降级为 user，目标用户ID=" + userId + "，roleId=" + userRole.getRoleId());
        logMessageSender.send(event);
    }

    @Override
    public List<Long> getAllUserRole(String roleCode) {
        // 1. 查询角色 ID
        Roles role = rolesMapper.selectOne(
                new QueryWrapper<Roles>().eq("role_code", roleCode)
        );

        if (role == null) {
            return Collections.emptyList();
        }
        // 2. 根据角色 ID 查询所有 userId
        List<UserRoles> userRoles = userRolesMapper.selectList(
                new QueryWrapper<UserRoles>().eq("role_id", role.getRoleId())
        );

        // MQ 日志
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(UserContext.getUserId());
        event.setAction("get_all_user_by_role");
        event.setIp(ip);
        event.setDetail("查询角色为 " + roleCode + " 的所有用户，roleId=" + role.getRoleId());
        logMessageSender.send(event);

        return userRoles.stream()
                .map(UserRoles::getUserId)
                .collect(Collectors.toList());
    }
}
